package com.xs.designpattern;

import java.util.HashSet;
import java.util.Set;

/**
 * 对象池
 * @author xs
 */
public abstract class ObjectPool<T> {
    /**
     * 可用的对象
     */
    private final Set<T> available = new HashSet<>();
    /**
     * 正在使用的对象
     */
    private final Set<T> inUse = new HashSet<>();

    /**
     * 创建对象
     * @return 对象
     */
    protected abstract T create();

    /**
     * 从池中检出对象
     */
    public synchronized T checkOut() {
        //判断可用的对象为空就创建对象
        if (available.isEmpty()) {
            available.add(create());
        }
        T instance = available.iterator().next();
        //拿到对象从可用的对象列表中移除放入正在使用的列表中
        available.remove(instance);
        inUse.add(instance);
        return instance;
    }

    /**
     * 放入对象池中
     * @param instance 对象
     */
    public synchronized void checkIn(T instance) {
        //把对象从正在使用移除，然后放入可用的列表中
        inUse.remove(instance);
        available.add(instance);
    }

    @Override
    public synchronized String toString() {
        return String.format("对象池中 可用的=%d 正在使用=%d", available.size(), inUse.size());
    }
}
